<template>
    <el-tree
        :data="treeData"
        :default-expand-all="true"
        :props="defaultProps"
        draggable
        :allow-drop="allowDrop"
        @node-drop="handleDrop">
        <span class="custom-tree-node" @click.stop="handleNodeClick(data, node)" slot-scope="{ node, data }">
            <span :class="{active: currentId === data.id,title: node.level === 1}">
                <span>{{ data.name }}</span>
                <span class="count" v-if="node.level === 1">({{ data.count }}/50)</span>
                <i class="el-icon-circle-plus-outline icon" v-if="node.level === 1" @click.stop="addType(data)"></i>
                <span class="count" v-else>({{ data.count }})</span>
            </span>
            <span class="tree-item-btn-box" v-if="node.level === 2">
                <i class="el-icon-edit" @click.stop="editType(data)"></i>
                <i class="el-icon-delete" @click.stop="deleteType(data)"></i>
            </span>
        </span>
    </el-tree>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import { State } from "vuex-class";
import { dialogType } from "@/views/declare-manage/src/components/dialog/index";

@Component
export default class TypeTree extends Vue {
    @State(state => state.authArea) authArea: any;

    treeData: any[] = []
    defaultProps = {
        children: "children",
        label: "name"
    }

    currentId = ""

    created() {
        this.getType();
    }

    async getType(type?: any) {
        const res = await this.$server["declare/getType"]({
            data: {
                cityCode: this.authArea.cityCode
            }
        });
        if (res.data.code === 200) {
            this.treeData = res.data.data;
            this.treeData[0].children.forEach((item: any) => {
                item.children = item.children || [];
            });
            if (!type) {
                this.currentId = this.treeData[0].children[0].id;
                // const ids = this.treeData[0].children.filter((item: any) => item.children && item.children.length).map((item: any) => item.children.map((cur: any) => cur.id));
                this.$emit("clickNode", { id: this.currentId });
            }
        } else {
            this.$message.error(res.data.message || "接口请求错误!");
        }
    }

    handleNodeClick(data: any, node: any) {
        this.currentId = data.id;
        if (node.level === 3) {
            this.$emit("clickNode", { id: data.id });
        } else if (node.level === 1) {
            const ids: any[] = this.treeData[0].children.map((item: any) => {
                return item.id;
            });
            this.$emit("clickNode", { id: ids.join() });
        } else {
            this.$emit("clickNode", { id: this.currentId });
        }
    }

    addType(data: any) {
        dialogType({
            sure: (vm: any, model: any) => {
                this.updateType({
                    name: model,
                    parentId: data.id
                }).then(() => {
                    vm.close();
                    this.getType();
                }).catch((e: any) => {
                    this.$message.error(e);
                });
            }
        });
    }

    editType(data: any) {
        dialogType({
            name: data.name,
            sure: (vm: any, model: any) => {
                this.updateType({
                    id: data.id,
                    name: model,
                    parentId: data.parentId
                }).then(() => {
                    vm.close();
                    this.getType();
                }).catch((e: any) => {
                    this.$message.error(e);
                });
            }
        });
    }

    deleteType(data: any) {
        if (data.count) {
            this.$message.error("当前分类下存在上报表单，请清空表单后，再进行此操作");
            return false;
        }
        this.$confirm("是否删除当前分类？", "提示")
            .then(async() => {
                const res = await this.$server["declare/deleteType"]({
                    data: {
                        id: data.id
                    }
                });
                if (res.data.code === 200) {
                    this.$message.success("删除成功");
                    this.getType();
                } else {
                    this.$message.error(res.data.message || "接口请求错误!");
                }
            })
            .catch();
    }

    updateType(data: any) {
        return new Promise(async(resolve, reject) => {
            const res = await this.$server["declare/addType"]({
                data: {
                    id: data.id || "",
                    name: data.name,
                    parentId: data.parentId,
                    cityCode: this.authArea.cityCode
                }
            });
            if (res.data.code === 200) {
                resolve(true);
            } else {
                reject(res.data.message || "接口请求错误!");
            }
        });
    }

    /**
     * 是否允许拖拽成功
     * @param draggingNode 被拖拽节点
     * @param dropNode 进入的节点
     * @param type 放置方式（prev，inner，next），目标节点前中后
     */
    allowDrop(draggingNode: any, dropNode: any, type: any) {
        // 不是第三层
        if (draggingNode.level !== 3) return false;
        // 放进去的只能是当前父节点
        if (type === "inner" && dropNode.id === draggingNode.data.parentId) return true;
        // 放前后的只能是兄弟节点
        if (type !== "inner" && dropNode.data.parentId === draggingNode.data.parentId) return true;
        return false;
    }

    // 拖拽成功后
    async handleDrop(draggingNode: any) {
        const parent = this.treeData[0].children.filter((item: any) => item.id === draggingNode.data.parentId);
        if (parent.length) {
            const ids = parent[0].children.map((item: any) => item.id);
            const res = await this.$server["declare/changeSort"]({
                data: ids
            });
            if (res.data.code !== 200) {
                this.$message.error(res.data.message || "接口请求错误!");
            }
        }
    }
}
</script>

<style lang="scss" scoped>
    .custom-tree-node {
        flex: 1;
        display: flex;
        align-items: center;
        justify-content: space-between;
        font-size: 14px;
        height: 26px;
        padding-right: 8px;
        .count {
            margin-left: 4px;
        }
        .active {
            color: #de2728;
        }
        .title {
            position: relative;
            width: 100%;
            .icon {
                position: absolute;
                right: 0;
                top: 50%;
                transform: translateY(-50%);
                font-size: 18px;
                color: #de2728;
            }
        }
        .tree-item-btn-box {
            display: none;
            i {
                font-size: 0.18rem;
                color: #bbb;
                margin-left: 4px;
            }
        }
        &:hover {
            .tree-item-btn-box {
                display: inline-block;
            }
        }
    }
</style>
